package control

import (
	"fmt"
	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/text"
	"image/color"
	"parkour/model"
	"parkour/tool"
	"time"
)

type Mode int

type Game struct {
	config         *model.Config
	bg             *model.Bg
	figure         *model.Figure
	bullets        map[*tool.Bullet]struct{}
	bullet         *tool.Bullet
	lastBulletTime time.Time
	entity         *model.Entity
	enemy          *model.Enemy
	coin           *model.Coin
	score          int
	mode           Mode
}

const (
	ModeStart Mode = iota
	ModeGame
	ModePause
	ModeOver
)

//var isBgMusicPaused bool

func NewGame() *Game {
	cfg := model.LoadConfig()
	ebiten.SetWindowSize(cfg.ScreenWidth, cfg.ScreenHeight)
	ebiten.SetWindowTitle("小游戏")
	game := &Game{
		config:  cfg,
		figure:  model.NewFigure(cfg),
		bg:      model.NewBg(),
		bullets: make(map[*tool.Bullet]struct{}),
		entity:  nil,
		enemy:   model.NewEnemy(cfg),
		coin:    model.NewCoin(cfg),
		score:   0,
	}
	//创建字体
	tool.CreateFonts(cfg)
	////金币的随机出现
	//rand.Seed(time.Now().UnixNano())
	//game.GenerateCoins(game.config.Nums)
	//game.score = game.Score()
	//障碍物的随机出现

	return game
}
func (g *Game) Score() int {
	return g.score
}

func (g *Game) Update() error {
	switch g.mode {
	case ModeStart:
		if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
			g.mode = ModeGame
		}
	case ModeGame:
		if ebiten.IsMouseButtonPressed(ebiten.MouseButtonRight) {
			g.mode = ModePause
		} else {
			tool.BgMusicPlayer.Play()
			err := model.Update(g.config)
			if err != nil {
				fmt.Println("背景移动失败")
				panic(err)
			}
			//人物移动
			g.figure.Move()
			//发射子弹
			g.Move(g.bullet)
			//子弹移动
			for bullet := range g.bullets {
				bullet.X += bullet.SpeedFactor
			}
			//子弹与敌人之间的碰撞
			for bullet := range g.bullets {
				for j, enemy := range g.enemy.Enemies {
					if tool.IsCollision(bullet.Entity, enemy.Entity) { // 使用类型断言进行转换
						//子弹碰到敌人
						delete(g.bullets, bullet)
						g.enemy.Enemies = append(g.enemy.Enemies[:j], g.enemy.Enemies[j+1:]...)
					}
				}
			}
			//子弹到达右边出界
			for bullet := range g.bullets {
				if bullet.OutOfScreen(g.config) {
					delete(g.bullets, bullet)
				}
			}
			g.enemy.CreateEnemy(g.config)
			//人物与敌人的碰撞
			for j, enemy := range g.enemy.Enemies {
				if tool.IsCollision(g.figure.Entity, enemy.Entity) { // 使用类型断言进行转换
					//人物碰到敌人 敌人消失 游戏失败
					if !tool.OverMusicPlayer.IsPlaying() {
						err := tool.OverMusicPlayer.Rewind()
						if err != nil {
							return err
						}
						tool.OverMusicPlayer.Play()
					} else {
						// 音效正在播放，重新设置播放位置
						err := tool.OverMusicPlayer.Rewind()
						if err != nil {
							return err
						}
					}
					g.enemy.Enemies = append(g.enemy.Enemies[:j], g.enemy.Enemies[j+1:]...)
					g.mode = ModeOver
					break
				}
			}
			g.coin.CreateCoin(g.config)
			//人物与金币的碰撞
			for i, c := range g.coin.Coins {
				if tool.IsCollision(g.figure.Entity, c.Entity) {
					//人物碰到金币 金币消失 分数加一
					if !tool.CoinMusicPlayer.IsPlaying() {
						err := tool.CoinMusicPlayer.Rewind()
						if err != nil {
							return err
						}
						tool.CoinMusicPlayer.Play()
					} else {
						// 音效正在播放，重新设置播放位置
						err := tool.CoinMusicPlayer.Rewind()
						if err != nil {
							return err
						}
					}
					g.score++
					g.coin.Coins = append(g.coin.Coins[:i], g.coin.Coins[i+1:]...)
					break
				}
			}
		}
	case ModePause:
		//暂停音乐
		tool.BgMusicPlayer.Pause()
		if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
			g.mode = ModeGame
		}
	case ModeOver:
		//关闭背景音乐
		err := tool.BgMusicPlayer.Close()
		if err != nil {
			fmt.Println("背景音乐关闭失败")
			panic(err)
		}
		if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
			//重新播放背景音乐
			err := tool.BgMusicPlayer.Rewind()
			if err != nil {
				fmt.Println("背景音乐重启失败")
				panic(err)
			}
			g.score = 0
			g.mode = ModeGame
		}
	}

	return nil
}

var (
	fontText     string
	textMessage  string
	scoreMessage string
)

func (g *Game) Draw(screen *ebiten.Image) {
	g.bg.Draw(screen)
	// ebitenutil.DebugPrint(screen, g.msg)
	switch g.mode {
	case ModeStart:
		fontText = "Click the mouse"
		scoreMessage = ""
	case ModeGame:
		fontText = ""
		textMessage = ""
		scoreMessage = fmt.Sprintf("score: %d", g.score)
		g.figure.Draw(screen, g.config)
		for bullet := range g.bullets {
			bullet.Draw(screen)
		}
		//金币和敌人的出现
		g.enemy.Draw(screen)
		g.coin.Draw(screen)

	case ModePause:
		fontText = ""
		textMessage = "Pause game"
		scoreMessage = fmt.Sprintf("score: %d", g.score)
		g.figure.Draw(screen, g.config)
		for bullet := range g.bullets {
			bullet.Draw(screen)
		}
		//金币和敌人的出现
		g.enemy.Draw(screen)
		g.coin.Draw(screen)
	case ModeOver:
		fontText = "Game over"
		textMessage = "Click the mouse"
		scoreMessage = ""
	}

	//添加字体
	x := (g.config.ScreenWidth + g.config.FontSize) / 3
	y := (g.config.ScreenHeight - g.config.FontSize) / 3
	textMessageY := (g.config.ScreenHeight - g.config.FontSize) / 2
	text.Draw(screen, fontText, tool.TextFont, x, y, color.White)
	text.Draw(screen, textMessage, tool.TextFont, x, textMessageY, color.White)
	text.Draw(screen, scoreMessage, tool.TextFont, x, y, color.White)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
	return g.config.ScreenWidth, g.config.ScreenHeight
}

// 添加子弹

func (g *Game) AddBullet(bullet *tool.Bullet) {
	g.bullets[bullet] = struct{}{}
}

// 子弹的发射
// 距离上次发射子弹的时间大于BulletInterval毫秒，才能再次发射，发射成功之后更新时间

func (g *Game) Move(bullet *tool.Bullet) {
	if ebiten.IsKeyPressed(ebiten.KeyAlt) {
		if len(g.bullets) < g.config.MaxBulletNum && time.Now().Sub(g.lastBulletTime).Milliseconds() > g.config.BulletInterval {
			if !tool.BulletMusicPlayer.IsPlaying() {
				err := tool.BulletMusicPlayer.Rewind()
				if err != nil {
					return
				}
				tool.BulletMusicPlayer.Play()
			} else {
				//正在播放的话，重新播放
				err := tool.BulletMusicPlayer.Rewind()
				if err != nil {
					return
				}
			}
			bullet := bullet.NewBullet(g.config, g.figure)
			g.AddBullet(bullet)
			g.lastBulletTime = time.Now()
		}
	}
}

func (g *Game) IsPaused() bool {
	return g.mode == ModePause
}
